package com.ijava.base.service.impl;


import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.sql.DataSource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.util.StringUtils;

import com.ijava.base.dao.ModelDAO;
import com.ijava.base.domain.Model;
import com.ijava.base.domain.User;
import com.ijava.base.service.ModelService;

public class ModelServiceImpl implements ModelService {
	private static final Logger logger = LoggerFactory.getLogger(ModelServiceImpl.class);
	private ModelDAO dao;
	private DataSource dataSource;

	public ModelDAO getDao() {
		return dao;
	}

	public void setDao(ModelDAO dao) {
		this.dao = dao;
	}

	public void remove(String id) throws Exception {
		dao.remove(id);
	}

	public void removeProcess(Model model) throws Exception {
		try {
			String pid = get(model.getModelId()).getModelParentId();
			remove(model.getModelId());
			Model parent = get(pid);
			if (null != parent) {
				List list = find(parent);
				if (list.size() == 0) {
					parent.setModelIsLeaf(1);
					update(parent);
				}
			}
		} catch (Exception e) {
			logger.error("", e);
			throw e;
		}
	}

	public void mutilRemove(Model model) throws Exception {
		try {
			String[] keys = model.getKeys();
			if(null == keys)
				return;
			for (int i = 0; i < keys.length; i++) {
				remove(keys[i]);
			}
		} catch (Exception e) {
			logger.error("", e);
			throw e;
		}
	}

	public void save(Model model) throws Exception {
		dao.save(model);
	}

	public String persist(Model model) throws Exception {
		try {
			JdbcTemplate template = new JdbcTemplate(getDataSource());
			List params = new ArrayList();
			params.add(model.getModelId());
			params.add(model.getModelParentId());
			params.add(model.getModelCode());
			params.add(model.getModelName());
			params.add(model.getModelIsLeaf());
			params.add(model.getModelLevel());
			params.add(model.getCrUserId());
			params.add(model.getCrTime());
			params.add(model.getRowEnable());
			params.add(model.getRowOrder());
			StringBuffer sqlBuffer = new StringBuffer(64);
			sqlBuffer.append("INSERT INTO MODEL (");
			sqlBuffer.append("MODEL_ID,MODEL_PARENT_ID,MODEL_CODE,MODEL_NAME,MODEL_IS_LEAF,");
			sqlBuffer.append("MODEL_LEVEL,CR_USER_ID,CR_TIME,ROW_ENABLE,ROW_ORDER");
			sqlBuffer.append(") VALUES(?,?,?,?,?,?,?,?,?,?)");
			template.update(sqlBuffer.toString(), params.toArray());
		} catch (Exception e) {
			logger.error("", e);
			model.setModelId(null);
			throw e;
		}
		return model.getModelId();
	}

	public void saveAll(Model model, User user) throws Exception {
		try {

			List models = new ArrayList();
			String[] modelIds = model.getModelIds();
			String[] modelCodes = model.getModelCodes();
			String[] modelNames = model.getModelNames();
			String[] modelExplains = model.getModelExplains();
			int[] modelIsLeafs = model.getModelIsLeafs();
			int[] rowOrders = model.getRowOrders();
			for (int i = 0; i < modelIds.length; i++) {
				Model e = new Model();
				if ("_".equals(modelIds[i])) {
					e.setModelId(null);
					e.setCrTime(new Date(System.currentTimeMillis()));
					e.setCrUserId(user.getUserId());
					e.setModelIsLeaf(1);
				} else {
					e.setModelId(modelIds[i]);
					e.setModelIsLeaf(modelIsLeafs[i]);
					e.setUpTime(new Date(System.currentTimeMillis()));
					e.setUpUserId(user.getUserId());
				}
				e.setModelLevel(model.getModelLevel() + 1);
				e.setModelParentId(model.getModelId());
				e.setRowEnable(1);
				e.setModelCode(modelCodes[i]);
				e.setModelName(modelNames[i]);
				e.setModelExplain(modelExplains[i]);
				e.setRowOrder(rowOrders[i]);

				models.add(e);
			}

			for (int i = 0; i < models.size(); i++) {
				Model mod = (Model) models.get(i);
				dao.saveOrUpdate(mod);
			}

			model = dao.get(model.getModelId());
			if (null != model) {
				model.setModelIsLeaf(0);
				dao.update(model);
			}
		} catch (Exception e) {
			logger.error("", e);
			throw e;
		}
	}

	public void update(Model model) throws Exception {
		dao.update(model);
	}

	public void merge(Model model) throws Exception {
		dao.merge(model);
	}

	public void saveOrUpdate(Model model) throws Exception {
		dao.saveOrUpdate(model);
	}

	public Model get(String id) throws Exception {
		return dao.get(id);
	}

	public List find(Model model) throws Exception {
		try {
			List paramList = new ArrayList();
			StringBuffer condition = new StringBuffer();

			condition.append(" where modelParentId = ?");
			paramList.add(model.getModelId());

			String queryString = "from " + Model.class.getName()
					+ condition.toString();
			return dao.find(queryString, paramList);
		} catch (Exception e) {
			logger.error("", e);
			throw e;
		}
	}

	public List findWithPaging(Model model) throws Exception {
		try {
			int firstRow = (model.getPageNo() - 1)
					* model.getPageSize();
			int maxRow = model.getPageSize();

			// JdbcTemplate template = new JdbcTemplate(dataSource);
			// int total =
			// template.queryForInt("SELECT COUNT(1) FROM TABLE_NAME");
			// model.setTotal(total);

			List paramList = new ArrayList();
			StringBuffer condition = new StringBuffer();
			if (StringUtils.hasLength(model.getModelId())) {
				condition.append(" where modelParentId = ?");
				paramList.add(model.getModelId());

				List list = dao.find("select count(*) from "
						+ Model.class.getName() + condition.toString(),
						paramList);
				model.setTotal(Integer.parseInt(list.get(0).toString()));

				String queryString = "from " + Model.class.getName()
						+ condition.toString();
				return dao.findWithPaging(queryString, paramList, firstRow,
						maxRow);
			} else {
				return new ArrayList();
			}
		} catch (Exception e) {
			logger.error("", e);
			throw e;
		}
	}

	public List findTree(String modelId, List list) throws Exception {
		try {
			List paramList = new ArrayList();
			paramList.add(modelId);

			List childList = dao.find("from " + Model.class.getName()
					+ " where modelParentId = ?", paramList);
			for (int i = 0; i < childList.size(); i++) {
				Model e = (Model) childList.get(i);
				list.add(e);
				if (e.getModelIsLeaf() == 0) {
					findTree(e.getModelId(), list);
				}
			}
		} catch (Exception e) {
			logger.error("", e);
			throw e;
		}
		return list;
	}

	public List findChild(Model model) throws Exception {
		try {
			List paramList = new ArrayList();
			String[] keys = model.getKeys();
			
			String sql = "from " + Model.class.getName()
					+ " where modelParentId = ?";
			if (null != keys && keys.length > 0) {
				StringBuffer condition = new StringBuffer("from "
						+ Model.class.getName()
						+ " where modelParentId in (");
				for (int i = 0; i < keys.length; i++) {
					paramList.add(keys[i]);
					condition.append("?");
					if (i != (keys.length - 1)) {
						condition.append(",");
					}
				}
				condition.append(")");
				sql = condition.toString();
			} else {
				paramList.add(model.getModelId());
			}
			return dao.find(sql, paramList);
		} catch (Exception e) {
			logger.error("", e);
			throw e;
		}
	}

	public DataSource getDataSource() {
		return dataSource;
	}

	public void setDataSource(DataSource dataSource) {
		this.dataSource = dataSource;
	}

}
